// $Id: ptr.hpp 2 2009-09-02 08:47:42Z joseph2002 $
/*
 * Copyright 2009 Joseph Wu
 * Distributed under the Boost Software License, Version 1.0.
 * (See accompanying file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
 *
 * For more information, see http://xpcomplus.sourceforge.net
 */

#ifndef XPCOM_PROXY_PTR_HPP
#define XPCOM_PROXY_PTR_HPP

#include <xpcom/config.hpp>
#include <xpcom/ptr.hpp>
#include <xpcom/detail/ptr_access.hpp>

#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_PREFIX
#endif

namespace xpcom {
namespace proxy {

using xpcom::detail::ptr_access;
using xpcom::detail::ptr_access_ptr;

//
// XPCOM proxy argument translators.
//
// ptr_in(noref_ptr<T>) --> T*
// ptr_in(const ref_ptr<T>&) --> T*
// ptr_in_void(noref_ptr<T>) --> void*
// ptr_in_void(const ref_ptr<T>&) --> void*
// ptr_out(ref_ptr<T>&) --> T**
// ptr_out_void(ref_ptr<T>&) --> void**
// ptr_inout(ref_ptr<T>&) --> T**
// ptr_inout_void(ref_ptr<T>&) --> void**
//

template <typename T>
XPCOM_FORCEINLINE
T* ptr_in(noref_ptr<T> p)
{
    return p.get();
}

template <typename T>
XPCOM_FORCEINLINE
T* ptr_in(const ref_ptr<T>& p)
{
    return p.get();
}

template <typename T>
XPCOM_FORCEINLINE
void* ptr_in_void(noref_ptr<T> p)
{
    return static_cast<void*>(p.get());
}

template <typename T>
XPCOM_FORCEINLINE
void* ptr_in_void(const ref_ptr<T>& p)
{
    return static_cast<void*>(p.get());
}

template <typename T>
XPCOM_FORCEINLINE
T** ptr_out(ref_ptr<T>& p)
{
    p.reset();
    return &ptr_access_ptr(p);
}

template <typename T>
XPCOM_FORCEINLINE
void** ptr_out_void(ref_ptr<T>& p)
{
    p.reset();
    return reinterpret_cast<void**>(&ptr_access_ptr(p));
}

template <typename T>
XPCOM_FORCEINLINE
T** ptr_inout(ref_ptr<T>& p)
{
    return &ptr_access_ptr(p);
}

template <typename T>
XPCOM_FORCEINLINE
void** ptr_inout_void(ref_ptr<T>& p)
{
    return reinterpret_cast<void**>(&ptr_access_ptr(p));
}

} // namespace xpcom::proxy
} // namespace xpcom

#ifdef BOOST_HAS_ABI_HEADERS
#include BOOST_ABI_SUFFIX
#endif

#endif // XPCOM_PROXY_PTR_HPP
